home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src / drawpix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  28.9 KB  |  1,025 lines

  1. /* $Id: drawpix.c,v 1.6 1997/02/10 20:26:57 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.2
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: drawpix.c,v $
  26.  * Revision 1.6  1997/02/10 20:26:57  brianp
  27.  * fixed memory leak in quickdraw_rgb()
  28.  *
  29.  * Revision 1.5  1997/02/03 20:30:31  brianp
  30.  * added a few DEFARRAY macros for BeOS
  31.  *
  32.  * Revision 1.4  1996/10/16 00:58:53  brianp
  33.  * renamed gl_drawpixels() to drawpixels()
  34.  *
  35.  * Revision 1.3  1996/09/27 01:26:25  brianp
  36.  * added missing default cases to switches
  37.  *
  38.  * Revision 1.2  1996/09/15 14:17:30  brianp
  39.  * now use GLframebuffer and GLvisual
  40.  *
  41.  * Revision 1.1  1996/09/13 01:38:16  brianp
  42.  * Initial revision
  43.  *
  44.  */
  45.  
  46.  
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #include "context.h"
  50. #include "drawpix.h"
  51. #include "feedback.h"
  52. #include "dlist.h"
  53. #include "macros.h"
  54. #include "pixel.h"
  55. #include "span.h"
  56. #include "stencil.h"
  57. #include "types.h"
  58.  
  59.  
  60.  
  61.  
  62. /* TODO:  apply texture mapping to fragments */
  63.  
  64.  
  65.  
  66. static void draw_index_pixels( GLcontext* ctx, GLsizei width, GLsizei height,
  67.                    GLenum type, const GLvoid *pixels )
  68. {
  69.    GLint x, y, desty;
  70.    GLuint i, j;
  71.    GLdepth zspan[MAX_WIDTH];
  72.    GLboolean zoom;
  73.  
  74.    zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  75.  
  76.    /* Position, depth of pixels */
  77.    x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  78.    y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  79.    desty = y;
  80.    if (ctx->Depth.Test) {
  81.       GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  82.       for (i=0;i<width;i++) {
  83.      zspan[i] = zval;
  84.       }
  85.    }
  86.  
  87.    /* process the image row by row */
  88.    for (i=0;i<height;i++,y++) {
  89.       GLuint ispan[MAX_WIDTH];
  90.  
  91.       /* convert to uints */
  92.       switch (type) {
  93.      case GL_UNSIGNED_BYTE:
  94.         {
  95.            GLubyte *src = (GLubyte *) pixels + i * width;
  96.            for (j=0;j<width;j++) {
  97.           ispan[j] = (GLuint) *src++;
  98.            }
  99.         }
  100.         break;
  101.      case GL_BYTE:
  102.         {
  103.            GLbyte *src = (GLbyte *) pixels + i * width;
  104.            for (j=0;j<width;j++) {
  105.           ispan[j] = (GLuint) *src++;
  106.            }
  107.         }
  108.         break;
  109.      case GL_UNSIGNED_SHORT:
  110.         {
  111.            GLushort *src = (GLushort *) pixels + i * width;
  112.            for (j=0;j<width;j++) {
  113.           ispan[j] = (GLuint) *src++;
  114.            }
  115.         }
  116.         break;
  117.      case GL_SHORT:
  118.         {
  119.            GLshort *src = (GLshort *) pixels + i * width;
  120.            for (j=0;j<width;j++) {
  121.           ispan[j] = (GLuint) *src++;
  122.            }
  123.         }
  124.         break;
  125.      case GL_UNSIGNED_INT:
  126.         {
  127.            GLuint *src = (GLuint *) pixels + i * width;
  128.            for (j=0;j<width;j++) {
  129.           ispan[j] = *src++;
  130.            }
  131.         }
  132.         break;
  133.      case GL_INT:
  134.         {
  135.            GLint *src = (GLint *) pixels + i * width;
  136.            for (j=0;j<width;j++) {
  137.           ispan[j] = (GLuint) *src++;
  138.            }
  139.         }
  140.         break;
  141.      case GL_BITMAP:
  142.         /* TODO */
  143.         break;
  144.      case GL_FLOAT:
  145.         {
  146.            GLfloat *src = (GLfloat *) pixels + i * width;
  147.            for (j=0;j<width;j++) {
  148.           ispan[j] = (GLuint) (GLint) *src++;
  149.            }
  150.         }
  151.         break;
  152.      default:
  153.         gl_error( ctx, GL_INVALID_ENUM, "Internal: draw_index_pixels" );
  154.       }
  155.  
  156.       /* apply shift and offset */
  157.       if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) {
  158.      if (ctx->Pixel.IndexShift>=0) {
  159.         for (j=0;j<width;j++) {
  160.            ispan[j] = (ispan[j] << ctx->Pixel.IndexShift)
  161.                   + ctx->Pixel.IndexOffset;
  162.         }
  163.      }
  164.      else {
  165.         for (j=0;j<width;j++) {
  166.            ispan[j] = (ispan[j] >> -ctx->Pixel.IndexShift)
  167.                   + ctx->Pixel.IndexOffset;
  168.         }
  169.      }
  170.       }
  171.  
  172.       if (ctx->Visual->RGBAflag) {
  173.      /* Convert index to RGBA and write to frame buffer */
  174.      GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  175.      GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  176.      for (j=0;j<width;j++) {
  177.         red[j]   = (GLint) (ctx->Pixel.MapItoR[ispan[j]] * ctx->Visual->RedScale);
  178.         green[j] = (GLint) (ctx->Pixel.MapItoG[ispan[j]] * ctx->Visual->GreenScale);
  179.         blue[j]  = (GLint) (ctx->Pixel.MapItoB[ispan[j]] * ctx->Visual->BlueScale);
  180.         alpha[j] = (GLint) (ctx->Pixel.MapItoA[ispan[j]] * ctx->Visual->AlphaScale);
  181.      }
  182.          if (zoom) {
  183.             gl_write_zoomed_color_span( ctx, width, x, y, zspan,
  184.                                         red, green, blue, alpha, desty );
  185.          }
  186.          else {
  187.             gl_write_color_span( ctx, width, x, y, zspan,
  188.                                  red, green, blue, alpha, GL_BITMAP );
  189.          }
  190.       }
  191.       else {
  192.      /* optionally apply index map then write to frame buffer */
  193.      if (ctx->Pixel.MapColorFlag) {
  194.         for (j=0;j<width;j++) {
  195.            ispan[j] = ctx->Pixel.MapItoI[ispan[j]];
  196.         }
  197.      }
  198.          if (zoom) {
  199.             gl_write_zoomed_index_span( ctx, width, x, y, zspan, ispan, desty );
  200.          }
  201.          else {
  202.             gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP );
  203.          }
  204.       }
  205.    }
  206.  
  207. }
  208.  
  209.  
  210.  
  211. static void draw_stencil_pixels( GLcontext* ctx, GLsizei width, GLsizei height,
  212.                      GLenum type, const GLvoid *pixels )
  213. {
  214.    GLint x, y, desty;
  215.    GLuint i, j;
  216.    GLboolean zoom;
  217.  
  218.    zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  219.  
  220.    /* Position, depth of pixels */
  221.    x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  222.    y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  223.    desty = y;
  224.  
  225.    /* process the image row by row */
  226.    for (i=0;i<height;i++,y++) {
  227.       GLubyte stencil[MAX_WIDTH];
  228.  
  229.       /* convert to ubytes */
  230.       switch (type) {
  231.      case GL_UNSIGNED_BYTE:
  232.         {
  233.            GLubyte *src = (GLubyte *) pixels + i * width;
  234.            MEMCPY( stencil, src, width );
  235.         }
  236.         break;
  237.      case GL_BYTE:
  238.         {
  239.            GLbyte *src = (GLbyte *) pixels + i * width;
  240.            MEMCPY( stencil, src, width );
  241.         }
  242.         break;
  243.      case GL_UNSIGNED_SHORT:
  244.         {
  245.            GLushort *src = (GLushort *) pixels + i * width;
  246.            for (j=0;j<width;j++) {
  247.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  248.            }
  249.         }
  250.         break;
  251.      case GL_SHORT:
  252.         {
  253.            GLshort *src = (GLshort *) pixels + i * width;
  254.            for (j=0;j<width;j++) {
  255.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  256.            }
  257.         }
  258.         break;
  259.      case GL_UNSIGNED_INT:
  260.         {
  261.            GLuint *src = (GLuint *) pixels + i * width;
  262.            for (j=0;j<width;j++) {
  263.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  264.            }
  265.         }
  266.         break;
  267.      case GL_INT:
  268.         {
  269.            GLint *src = (GLint *) pixels + i * width;
  270.            for (j=0;j<width;j++) {
  271.           stencil[j] = (GLubyte) ((*src++) & 0xff);
  272.            }
  273.         }
  274.         break;
  275.      case GL_BITMAP:
  276.         /* TODO */
  277.         break;
  278.      case GL_FLOAT:
  279.         {
  280.            GLfloat *src = (GLfloat *) pixels + i * width;
  281.            for (j=0;j<width;j++) {
  282.           stencil[j] = (GLubyte) (((GLint) *src++) & 0xff);
  283.            }
  284.         }
  285.         break;
  286.      default:
  287.         gl_error( ctx, GL_INVALID_ENUM, "Internal: draw_stencil_pixels" );
  288.       }
  289.  
  290.       /* apply shift and offset */
  291.       if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) {
  292.      if (ctx->Pixel.IndexShift>=0) {
  293.         for (j=0;j<width;j++) {
  294.            stencil[j] = (stencil[j] << ctx->Pixel.IndexShift)
  295.                   + ctx->Pixel.IndexOffset;
  296.         }
  297.      }
  298.      else {
  299.         for (j=0;j<width;j++) {
  300.            stencil[j] = (stencil[j] >> -ctx->Pixel.IndexShift)
  301.                   + ctx->Pixel.IndexOffset;
  302.         }
  303.      }
  304.       }
  305.  
  306.       /* mapping */
  307.       if (ctx->Pixel.MapStencilFlag) {
  308.      for (j=0;j<width;j++) {
  309.         stencil[j] = ctx->Pixel.MapStoS[ stencil[j] ];
  310.      }
  311.       }
  312.  
  313.       /* write stencil values to stencil buffer */
  314.       if (zoom) {
  315.          gl_write_zoomed_stencil_span( ctx, (GLuint) width, x, y, stencil, desty );
  316.       }
  317.       else {
  318.          gl_write_stencil_span( ctx, (GLuint) width, x, y, stencil );
  319.       }
  320.    }
  321. }
  322.  
  323.  
  324.  
  325. static void draw_depth_pixels( GLcontext* ctx, GLsizei width, GLsizei height,
  326.                    GLenum type, const GLvoid *pixels )
  327. {
  328.    GLint x, y, desty;
  329.    GLubyte red[MAX_WIDTH], green[MAX_WIDTH], blue[MAX_WIDTH], alpha[MAX_WIDTH];
  330.    GLuint ispan[MAX_WIDTH];
  331.    GLboolean bias_or_scale;
  332.    GLboolean zoom;
  333.  
  334.    bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
  335.    zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  336.  
  337.    /* Position, depth of pixels */
  338.    x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  339.    y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  340.    desty = y;
  341.  
  342.    /* Color or index */
  343.    if (ctx->Visual->RGBAflag) {
  344.       GLint r, g, b, a;
  345.       r = (GLint) (ctx->Current.RasterColor[0] * ctx->Visual->RedScale);
  346.       g = (GLint) (ctx->Current.RasterColor[1] * ctx->Visual->GreenScale);
  347.       b = (GLint) (ctx->Current.RasterColor[2] * ctx->Visual->BlueScale);
  348.       a = (GLint) (ctx->Current.RasterColor[3] * ctx->Visual->AlphaScale);
  349.       MEMSET( red,   r, width );
  350.       MEMSET( green, g, width );
  351.       MEMSET( blue,  b, width );
  352.       MEMSET( alpha, a, width );
  353.    }
  354.    else {
  355.       GLuint i;
  356.       for (i=0;i<width;i++) {
  357.      ispan[i] = ctx->Current.RasterIndex;
  358.       }
  359.    }
  360.  
  361.    if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
  362.        && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) {
  363.       /* Special case: directly write 16-bit depth values */
  364.       GLuint j;
  365.       for (j=0;j<height;j++,y++) {
  366.          GLdepth *zptr = (GLdepth *) pixels + j * width;
  367.          gl_write_color_span( ctx, width, x, y, zptr,
  368.                               red, green, blue, alpha, GL_BITMAP );
  369.       }
  370.    }
  371.    else if (type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint)
  372.        && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) {
  373.       /* Special case: directly write 32-bit depth values */
  374.       GLuint i, j;
  375.       /* Compute shift value to scale 32-bit uints down to depth values. */
  376.       GLuint shift = 0;
  377.       GLuint max = MAX_DEPTH;
  378.       while ((max&0x80000000)==0) {
  379.          max = max << 1;
  380.          shift++;
  381.       }
  382.       for (j=0;j<height;j++,y++) {
  383.          GLdepth zspan[MAX_WIDTH];
  384.          GLuint *zptr = (GLuint *) pixels + j * width;
  385.          for (i=0;i<width;i++) {
  386.             zspan[i] = zptr[i] >> shift;
  387.          }
  388.          gl_write_color_span( ctx, width, x, y, zspan,
  389.                               red, green, blue, alpha, GL_BITMAP );
  390.       }
  391.    }
  392.    else {
  393.       /* General case (slower) */
  394.       GLuint i, j;
  395.  
  396.       /* process image row by row */
  397.       for (i=0;i<height;i++,y++) {
  398.          GLfloat depth[MAX_WIDTH];
  399.          GLdepth zspan[MAX_WIDTH];
  400.  
  401.          switch (type) {
  402.             case GL_UNSIGNED_BYTE:
  403.                {
  404.                   GLubyte *src = (GLubyte *) pixels + i * width;
  405.                   for (j=0;j<width;j++) {
  406.                      depth[j] = UBYTE_TO_FLOAT( *src++ );
  407.                   }
  408.                }
  409.                break;
  410.             case GL_BYTE:
  411.                {
  412.                   GLbyte *src = (GLbyte *) pixels + i * width;
  413.                   for (j=0;j<width;j++) {
  414.                      depth[j] = BYTE_TO_FLOAT( *src++ );
  415.                   }
  416.                }
  417.                break;
  418.             case GL_UNSIGNED_SHORT:
  419.                {
  420.                   GLushort *src = (GLushort *) pixels + i * width;
  421.                   for (j=0;j<width;j++) {
  422.                      depth[j] = USHORT_TO_FLOAT( *src++ );
  423.                   }
  424.                }
  425.                break;
  426.             case GL_SHORT:
  427.                {
  428.                   GLshort *src = (GLshort *) pixels + i * width;
  429.                   for (j=0;j<width;j++) {
  430.                      depth[j] = SHORT_TO_FLOAT( *src++ );
  431.                   }
  432.                }
  433.                break;
  434.             case GL_UNSIGNED_INT:
  435.                {
  436.                   GLuint *src = (GLuint *) pixels + i * width;
  437.                   for (j=0;j<width;j++) {
  438.                      depth[j] = UINT_TO_FLOAT( *src++ );
  439.                   }
  440.                }
  441.                break;
  442.             case GL_INT:
  443.                {
  444.                   GLint *src = (GLint *) pixels + i * width;
  445.                   for (j=0;j<width;j++) {
  446.                      depth[j] = INT_TO_FLOAT( *src++ );
  447.                   }
  448.                }
  449.                break;
  450.             case GL_FLOAT:
  451.                {
  452.                   GLfloat *src = (GLfloat *) pixels + i * width;
  453.                   for (j=0;j<width;j++) {
  454.                      depth[j] = *src++;
  455.                   }
  456.                }
  457.                break;
  458.             default:
  459.                abort();
  460.          }
  461.  
  462.          /* apply depth scale and bias */
  463.          if (ctx->Pixel.DepthScale!=1.0 || ctx->Pixel.DepthBias!=0.0) {
  464.             for (j=0;j<width;j++) {
  465.                depth[j] = depth[j] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
  466.             }
  467.          }
  468.  
  469.          /* clamp depth values to [0,1] and convert from floats to integers */
  470.          for (j=0;j<width;j++) {
  471.             zspan[j] = (GLdepth) (CLAMP( depth[j], 0.0F, 1.0F ) * DEPTH_SCALE);
  472.          }
  473.  
  474.          if (ctx->Visual->RGBAflag) {
  475.             if (zoom) {
  476.                gl_write_zoomed_color_span( ctx, width, x, y, zspan,
  477.                                            red, green, blue, alpha, desty );
  478.             }
  479.             else {
  480.                gl_write_color_span( ctx, width, x, y, zspan,
  481.                                     red, green, blue, alpha, GL_BITMAP );
  482.             }
  483.          }
  484.          else {
  485.             if (zoom) {
  486.                gl_write_zoomed_index_span( ctx, width, x, y, zspan,
  487.                                            ispan, GL_BITMAP );
  488.             }
  489.             else {
  490.                gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP );
  491.             }
  492.          }
  493.  
  494.       }
  495.    }
  496. }
  497.  
  498.  
  499.  
  500. static void draw_color_pixels( GLcontext* ctx,
  501.                                GLsizei width, GLsizei height, GLenum format,
  502.                    GLenum type, const GLvoid *pixels )
  503. {
  504.    GLuint i, j;
  505.    GLint x, y, desty;
  506.    GLdepth zspan[MAX_WIDTH];
  507.    GLboolean scale_or_bias, quick_draw;
  508.    GLboolean zoom;
  509.  
  510.    zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  511.  
  512.    /* Position, depth of pixels */
  513.    x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  514.    y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  515.    desty = y;
  516.    if (ctx->Depth.Test) {
  517.       /* fill in array of z values */
  518.       GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  519.       for (i=0;i<width;i++) {
  520.      zspan[i] = z;
  521.       }
  522.    }
  523.  
  524.    /* Determine if scaling and/or biasing is needed */
  525.    if (ctx->Pixel.RedScale!=1.0F   || ctx->Pixel.RedBias!=0.0F ||
  526.        ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
  527.        ctx->Pixel.BlueScale!=1.0F  || ctx->Pixel.BlueBias!=0.0F ||
  528.        ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
  529.       scale_or_bias = GL_TRUE;
  530.    }
  531.    else {
  532.       scale_or_bias = GL_FALSE;
  533.    }
  534.  
  535.    /* Determine if we can directly call the device driver function */
  536.    if (ctx->RasterMask==0 && !zoom && x>=0 && y>=0
  537.        && x+width<=ctx->Buffer->Width && y+height<=ctx->Buffer->Height) {
  538.       quick_draw = GL_TRUE;
  539.    }
  540.    else {
  541.       quick_draw = GL_FALSE;
  542.    }
  543.  
  544.    /* First check for common cases */
  545.    if (type==GL_UNSIGNED_BYTE && (format==GL_RGB || format == GL_LUMINANCE)
  546.        && !ctx->Pixel.MapColorFlag && !scale_or_bias
  547.        && ctx->Visual->EightBitColor) {
  548.       DEFARRAY( GLubyte, alpha, MAX_WIDTH );
  549.       GLubyte *src = (GLubyte *) pixels;
  550.       /* constant alpha */
  551.       MEMSET( alpha, (GLint) ctx->Visual->AlphaScale, width );
  552.       if (format == GL_RGB) {
  553.      /* 8-bit RGB pixels */
  554.      DEFARRAY( GLubyte, red, MAX_WIDTH );
  555.      DEFARRAY( GLubyte, green, MAX_WIDTH );
  556.      DEFARRAY( GLubyte, blue, MAX_WIDTH );
  557.      for (i=0;i<height;i++,y++) {
  558.         for (j=0;j<width;j++) {
  559.            red[j]   = *src++;
  560.            green[j] = *src++;
  561.            blue[j]  = *src++;
  562.         }
  563.         if (quick_draw) {
  564.            (*ctx->Driver.WriteColorSpan)( ctx, width, x, y,
  565.                                               red, green, blue, alpha, NULL);
  566.         }
  567.         else if (zoom) {
  568.            gl_write_zoomed_color_span( ctx, (GLuint) width, x, y, zspan,
  569.                        red, green, blue, alpha, desty );
  570.         }
  571.         else {
  572.            gl_write_color_span( ctx, (GLuint) width, x, y, zspan,
  573.                     red, green, blue, alpha, GL_BITMAP );
  574.         }
  575.      }
  576.      UNDEFARRAY( red );
  577.      UNDEFARRAY( green );
  578.      UNDEFARRAY( blue );
  579.       }
  580.       else {
  581.      /* 8-bit Luminance pixels */
  582.      GLubyte *lum = (GLubyte *) pixels;
  583.      for (i=0;i<height;i++,y++,lum+=width) {
  584.         if (quick_draw) {
  585.            (*ctx->Driver.WriteColorSpan)( ctx, width, x,y,
  586.                                               lum, lum, lum, alpha, NULL);
  587.         }
  588.         else if (zoom) {
  589.            gl_write_zoomed_color_span( ctx, (GLuint) width, x, y, zspan,
  590.                        lum, lum, lum, alpha, desty );
  591.         }
  592.         else {
  593.            gl_write_color_span( ctx, (GLuint) width, x, y, zspan,
  594.                     lum, lum, lum, alpha, GL_BITMAP );
  595.         }
  596.      }
  597.       }
  598.       UNDEFARRAY( alpha );
  599.    }
  600.    else {
  601.       /* General solution */
  602.       GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
  603.       GLuint components;
  604.  
  605.       r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
  606.       switch (format) {
  607.      case GL_RED:
  608.         r_flag = GL_TRUE;
  609.         components = 1;
  610.         break;
  611.      case GL_GREEN:
  612.         g_flag = GL_TRUE;
  613.         components = 1;
  614.         break;
  615.      case GL_BLUE:
  616.         b_flag = GL_TRUE;
  617.         components = 1;
  618.         break;
  619.      case GL_ALPHA:
  620.         a_flag = GL_TRUE;
  621.         components = 1;
  622.         break;
  623.      case GL_RGB:
  624.         r_flag = g_flag = b_flag = GL_TRUE;
  625.         components = 3;
  626.         break;
  627.      case GL_LUMINANCE:
  628.         l_flag = GL_TRUE;
  629.         components = 1;
  630.         break;
  631.      case GL_LUMINANCE_ALPHA:
  632.         l_flag = a_flag = GL_TRUE;
  633.         components = 2;
  634.         break;
  635.      case GL_RGBA:
  636.         r_flag = g_flag = b_flag = a_flag = GL_TRUE;
  637.         components = 4;
  638.         break;
  639.          default:
  640.             abort();
  641.       }
  642.  
  643.       /* process the image row by row */
  644.       for (i=0;i<height;i++,y++) {
  645.          DEFARRAY(GLfloat, rf, MAX_WIDTH);
  646.          DEFARRAY(GLfloat, gf, MAX_WIDTH);
  647.          DEFARRAY(GLfloat, bf, MAX_WIDTH);
  648.          DEFARRAY(GLfloat, af, MAX_WIDTH);
  649.          DEFARRAY(GLubyte, red, MAX_WIDTH);
  650.          DEFARRAY(GLubyte, green, MAX_WIDTH);
  651.          DEFARRAY(GLubyte, blue, MAX_WIDTH);
  652.          DEFARRAY(GLubyte, alpha, MAX_WIDTH);
  653.  
  654.      /* convert to floats */
  655.      switch (type) {
  656.         case GL_UNSIGNED_BYTE:
  657.            {
  658.           GLubyte *src = (GLubyte *) pixels + i * width * components;
  659.           for (j=0;j<width;j++) {
  660.              if (l_flag) {
  661.             rf[j] = gf[j] = bf[j] = UBYTE_TO_FLOAT(*src++);
  662.              }
  663.              else {
  664.             rf[j] = r_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  665.             gf[j] = g_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  666.             bf[j] = b_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  667.              }
  668.              af[j] = a_flag ? UBYTE_TO_FLOAT(*src++) : 1.0;
  669.           }
  670.            }
  671.            break;
  672.         case GL_BYTE:
  673.            {
  674.           GLbyte *src = (GLbyte *) pixels + i * width * components;
  675.           for (j=0;j<width;j++) {
  676.              if (l_flag) {
  677.             rf[j] = gf[j] = bf[j] = BYTE_TO_FLOAT(*src++);
  678.              }
  679.              else {
  680.             rf[j] = r_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  681.             gf[j] = g_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  682.             bf[j] = b_flag ? BYTE_TO_FLOAT(*src++) : 0.0;
  683.              }
  684.              af[j] = a_flag ? BYTE_TO_FLOAT(*src++) : 1.0;
  685.           }
  686.            }
  687.            break;
  688.         case GL_BITMAP:
  689.            /* special case */
  690.            break;
  691.         case GL_UNSIGNED_SHORT:
  692.            {
  693.           GLushort *src = (GLushort *) pixels + i * width * components;
  694.           for (j=0;j<width;j++) {
  695.              if (l_flag) {
  696.             rf[j] = gf[j] = bf[j] = USHORT_TO_FLOAT(*src++);
  697.              }
  698.              else {
  699.             rf[j] = r_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  700.             gf[j] = g_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  701.             bf[j] = b_flag ? USHORT_TO_FLOAT(*src++) : 0.0;
  702.              }
  703.              af[j] = a_flag ? USHORT_TO_FLOAT(*src++) : 1.0;
  704.           }
  705.            }
  706.            break;
  707.         case GL_SHORT:
  708.            {
  709.           GLshort *src = (GLshort *) pixels + i * width * components;
  710.           for (j=0;j<width;j++) {
  711.              if (l_flag) {
  712.             rf[j] = gf[j] = bf[j] = SHORT_TO_FLOAT(*src++);
  713.              }
  714.              else {
  715.             rf[j] = r_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  716.             gf[j] = g_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  717.             bf[j] = b_flag ? SHORT_TO_FLOAT(*src++) : 0.0;
  718.              }
  719.              af[j] = a_flag ? SHORT_TO_FLOAT(*src++) : 1.0;
  720.           }
  721.            }
  722.            break;
  723.         case GL_UNSIGNED_INT:
  724.            {
  725.           GLuint *src = (GLuint *) pixels + i * width * components;
  726.           for (j=0;j<width;j++) {
  727.              if (l_flag) {
  728.             rf[j] = gf[j] = bf[j] = UINT_TO_FLOAT(*src++);
  729.              }
  730.              else {
  731.             rf[j] = r_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  732.             gf[j] = g_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  733.             bf[j] = b_flag ? UINT_TO_FLOAT(*src++) : 0.0;
  734.              }
  735.              af[j] = a_flag ? af[j] = UINT_TO_FLOAT(*src++) : 1.0;
  736.           }
  737.            }
  738.            break;
  739.         case GL_INT:
  740.            {
  741.           GLint *src = (GLint *) pixels + i * width * components;
  742.           for (j=0;j<width;j++) {
  743.              if (l_flag) {
  744.             rf[j] = gf[j] = bf[j] = INT_TO_FLOAT(*src++);
  745.              }
  746.              else {
  747.             rf[j] = r_flag ? INT_TO_FLOAT(*src++) : 0.0;
  748.             gf[j] = g_flag ? INT_TO_FLOAT(*src++) : 0.0;
  749.             bf[j] = b_flag ? INT_TO_FLOAT(*src++) : 0.0;
  750.              }
  751.              af[j] = a_flag ? INT_TO_FLOAT(*src++) : 1.0;
  752.           }
  753.            }
  754.            break;
  755.         case GL_FLOAT:
  756.            {
  757.           GLfloat *src = (GLfloat *) pixels + i * width * components;
  758.           for (j=0;j<width;j++) {
  759.              if (l_flag) {
  760.             rf[j] = gf[j] = bf[j] = *src++;
  761.              }
  762.              else {
  763.             rf[j] = r_flag ? *src++ : 0.0;
  764.             gf[j] = g_flag ? *src++ : 0.0;
  765.             bf[j] = b_flag ? *src++ : 0.0;
  766.              }
  767.              af[j] = a_flag ? *src++ : 1.0;
  768.           }
  769.            }
  770.            break;
  771.         default:
  772.            gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels" );
  773.            return;
  774.      }
  775.  
  776.      /* apply scale and bias */
  777.      if (scale_or_bias) {
  778.         for (j=0;j<width;j++) {
  779.            GLfloat r, g, b, a;
  780.            r = rf[j] * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  781.            g = gf[j] * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  782.            b = bf[j] * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  783.            a = af[j] * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  784.            rf[j] = CLAMP( r, 0.0, 1.0 );
  785.            gf[j] = CLAMP( g, 0.0, 1.0 );
  786.            bf[j] = CLAMP( b, 0.0, 1.0 );
  787.            af[j] = CLAMP( a, 0.0, 1.0 );
  788.         }
  789.      }
  790.  
  791.      /* apply pixel mappings */
  792.      if (ctx->Pixel.MapColorFlag) {
  793.             GLfloat rscale = ctx->Pixel.MapRtoRsize-1;
  794.             GLfloat gscale = ctx->Pixel.MapGtoGsize-1;
  795.             GLfloat bscale = ctx->Pixel.MapBtoBsize-1;
  796.             GLfloat ascale = ctx->Pixel.MapAtoAsize-1;
  797.         for (j=0;j<width;j++) {
  798.            rf[j] = ctx->Pixel.MapRtoR[ (GLint) (rf[j] * rscale) ];
  799.            gf[j] = ctx->Pixel.MapGtoG[ (GLint) (gf[j] * gscale) ];
  800.            bf[j] = ctx->Pixel.MapBtoB[ (GLint) (bf[j] * bscale) ];
  801.            af[j] = ctx->Pixel.MapAtoA[ (GLint) (af[j] * ascale) ];
  802.         }
  803.      }
  804.  
  805.      /* convert to integers */
  806.      for (j=0;j<width;j++) {
  807.         red[j]   = (GLint) (rf[j] * ctx->Visual->RedScale);
  808.         green[j] = (GLint) (gf[j] * ctx->Visual->GreenScale);
  809.         blue[j]  = (GLint) (bf[j] * ctx->Visual->BlueScale);
  810.         alpha[j] = (GLint) (af[j] * ctx->Visual->AlphaScale);
  811.      }
  812.  
  813.      /* write to frame buffer */
  814.          if (quick_draw) {
  815.             (*ctx->Driver.WriteColorSpan)( ctx, width, x, y,
  816.                                            red, green, blue, alpha, NULL);
  817.          }
  818.          else if (zoom) {
  819.             gl_write_zoomed_color_span( ctx, width, x, y, zspan,
  820.                                         red, green, blue, alpha, desty );
  821.          }
  822.          else {
  823.             gl_write_color_span( ctx, (GLuint) width, x, y, zspan,
  824.                                  red, green, blue, alpha, GL_BITMAP );
  825.          }
  826.  
  827.          UNDEFARRAY(red);
  828.          UNDEFARRAY(green);
  829.          UNDEFARRAY(blue);
  830.          UNDEFARRAY(alpha);
  831.       }
  832.    }
  833.  
  834. }
  835.  
  836.  
  837.  
  838. /*
  839.  * Do a glDrawPixels( w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels ) optimized
  840.  * for the case of no pixel mapping, no scale, no bias, no zoom, default
  841.  * storage mode, no raster ops, and no pixel clipping.
  842.  * Return:  GL_TRUE if success
  843.  *          GL_FALSE if conditions weren't met for optimized drawing
  844.  */
  845. static GLboolean quickdraw_rgb( GLcontext* ctx, GLsizei width, GLsizei height,
  846.                                 const void *pixels )
  847. {
  848.    DEFARRAY( GLubyte, red, MAX_WIDTH );
  849.    DEFARRAY( GLubyte, green, MAX_WIDTH );
  850.    DEFARRAY( GLubyte, blue, MAX_WIDTH );
  851.    DEFARRAY( GLubyte, alpha, MAX_WIDTH );
  852.    GLint i, j;
  853.    GLint x, y;
  854.    GLint bytes_per_row;
  855.    GLboolean result;
  856.  
  857.    bytes_per_row = width * 3 + (width % ctx->Unpack.Alignment);
  858.  
  859.    if (!ctx->Current.RasterPosValid) {
  860.       /* This is success, actually. */
  861.       result = GL_TRUE;
  862.    }
  863.    else {
  864.       x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  865.       y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  866.  
  867.       if (x<0 || y<0
  868.           || x+width>ctx->Buffer->Width || y+height>ctx->Buffer->Height) {
  869.          result = GL_FALSE;  /* can't handle this situation */
  870.       }
  871.       else {
  872.          /* constant alpha */
  873.          for (j=0;j<width;j++) {
  874.             alpha[j] = (GLint) ctx->Visual->AlphaScale;
  875.          }
  876.  
  877.          /* write directly to device driver */
  878.          for (i=0;i<height;i++) {
  879.             /* each row of pixel data starts at 4-byte boundary */
  880.             GLubyte *src = (GLubyte *) pixels + i * bytes_per_row;
  881.             for (j=0;j<width;j++) {
  882.                red[j]   = *src++;
  883.                green[j] = *src++;
  884.                blue[j]  = *src++;
  885.             }
  886.             (*ctx->Driver.WriteColorSpan)( ctx, width, x, y+i,
  887.                                            red, green, blue, alpha, NULL);
  888.          }
  889.          result = GL_TRUE;
  890.       }
  891.    }
  892.  
  893.    UNDEFARRAY( red );
  894.    UNDEFARRAY( green );
  895.    UNDEFARRAY( blue );
  896.    UNDEFARRAY( alpha );
  897.  
  898.    return result;
  899. }
  900.  
  901.  
  902.  
  903. /*
  904.  * Implements general glDrawPixels operation.
  905.  */
  906. static void drawpixels( GLcontext* ctx, GLsizei width, GLsizei height,
  907.                         GLenum format, GLenum type, const GLvoid *pixels )
  908. {
  909.    if (INSIDE_BEGIN_END(ctx)) {
  910.       gl_error( ctx, GL_INVALID_OPERATION, "glDrawPixels" );
  911.       return;
  912.    }
  913.  
  914.    if (ctx->NewState) {
  915.       gl_update_state(ctx);
  916.    }
  917.  
  918.    if (ctx->RenderMode==GL_RENDER) {
  919.       if (!ctx->Current.RasterPosValid) {
  920.      return;
  921.       }
  922.       switch (format) {
  923.      case GL_COLOR_INDEX:
  924.             draw_index_pixels( ctx, width, height, type, pixels );
  925.         break;
  926.      case GL_STENCIL_INDEX:
  927.         draw_stencil_pixels( ctx, width, height, type, pixels );
  928.         break;
  929.      case GL_DEPTH_COMPONENT:
  930.         draw_depth_pixels( ctx, width, height, type, pixels );
  931.         break;
  932.      case GL_RED:
  933.      case GL_GREEN:
  934.      case GL_BLUE:
  935.      case GL_ALPHA:
  936.      case GL_RGB:
  937.      case GL_LUMINANCE:
  938.      case GL_LUMINANCE_ALPHA:
  939.      case GL_RGBA:
  940.             draw_color_pixels( ctx, width, height, format, type, pixels );
  941.         break;
  942.      default:
  943.         gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels" );
  944.       }
  945.    }
  946.    else if (ctx->RenderMode==GL_FEEDBACK) {
  947.       GLfloat color[4], texcoord[4], invq;
  948.       color[0] = ctx->Current.IntColor[0] * ctx->Visual->InvRedScale;
  949.       color[1] = ctx->Current.IntColor[1] * ctx->Visual->InvGreenScale;
  950.       color[2] = ctx->Current.IntColor[2] * ctx->Visual->InvBlueScale;
  951.       color[3] = ctx->Current.IntColor[3] * ctx->Visual->InvAlphaScale;
  952.       invq = 1.0F / ctx->Current.TexCoord[3];
  953.       texcoord[0] = ctx->Current.TexCoord[0] * invq;
  954.       texcoord[1] = ctx->Current.TexCoord[1] * invq;
  955.       texcoord[2] = ctx->Current.TexCoord[2] * invq;
  956.       texcoord[3] = ctx->Current.TexCoord[3];
  957.       FEEDBACK_TOKEN( ctx, (GLfloat) GL_DRAW_PIXEL_TOKEN );
  958.       gl_feedback_vertex( ctx, ctx->Current.RasterPos[0],
  959.               ctx->Current.RasterPos[1],
  960.               ctx->Current.RasterPos[2],
  961.               ctx->Current.RasterPos[3],
  962.               color, ctx->Current.Index, texcoord );
  963.    }
  964.    else if (ctx->RenderMode==GL_SELECT) {
  965.       gl_update_hitflag( ctx, ctx->Current.RasterPos[2] );
  966.    }
  967. }
  968.  
  969.  
  970.  
  971. /*
  972.  * Compile OR Execute a glDrawPixels!
  973.  */
  974. void gl_DrawPixels( GLcontext* ctx, GLsizei width, GLsizei height,
  975.                     GLenum format, GLenum type, const GLvoid *pixels )
  976. {
  977.    GLvoid *image;
  978.  
  979.    if (width<0 || height<0) {
  980.       gl_error( ctx, GL_INVALID_VALUE, "glDrawPixels" );
  981.       return;
  982.    }
  983.  
  984.    /* Let the device driver take a crack at glDrawPixels */
  985.    if (!ctx->CompileFlag && ctx->Driver.DrawPixels) {
  986.       GLint x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  987.       GLint y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  988.       if ((*ctx->Driver.DrawPixels)( ctx, x, y, width, height,
  989.                                       format, type, GL_FALSE, pixels )) {
  990.          /* Device driver did the job */
  991.          return;
  992.       }
  993.    }
  994.  
  995.    if (format==GL_RGB && type==GL_UNSIGNED_BYTE && ctx->FastDrawPixels
  996.        && !ctx->CompileFlag && ctx->RenderMode==GL_RENDER
  997.        && ctx->RasterMask==0) {
  998.       /* optimized path */
  999.       if (quickdraw_rgb( ctx, width, height, pixels )) {
  1000.          /* success */
  1001.          return;
  1002.       }
  1003.    }
  1004.  
  1005.    /* take the general path */
  1006.    image = gl_unpack_pixels( ctx, width, height, format, type, pixels );
  1007.    if (!image) {
  1008.       gl_error( ctx, GL_OUT_OF_MEMORY, "glDrawPixels" );
  1009.       return;
  1010.    }
  1011.  
  1012.    if (ctx->CompileFlag) {
  1013.       gl_save_DrawPixels( ctx, width, height, format, type, image );
  1014.    }
  1015.    if (ctx->ExecuteFlag) {
  1016.       drawpixels( ctx, width, height, format, type, image );
  1017.       if (!ctx->CompileFlag) {
  1018.          /* may discard unpacked image now */
  1019.          free( image );
  1020.       }
  1021.    }
  1022. }
  1023.  
  1024.  
  1025.